昨天設定完 employer-list,現在我們把 CURD 中的 C 完成,顧名思義就是 創造 - 新增 的意思,我們要在畫面上新增一個表單,讓使用者可以直接用這個表單新增一個老闆的資料
<!-- 老闆列表頁 -->
http://127.0.0.1:8000/online/employer/create/
url 路徑設定
# online/urls.py
urlpatterns += [
path("employer/create/", views.EmployerCreate.as_view(), name="employer-create")
]
這邊比較特別的是 EmployerCreate,不過他跟 EmployerListView 一樣,都是等等會在 views.py 檔案新增的 類別 class
路徑設定好了,接下來當然是收發 request/response 的 views.py 檔案:
# online/views.py
# ... 省略
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
# create
class EmployerCreate(CreateView):
model = Employer
fields = '__all__'
success_url = reverse_lazy('employer-list')
這邊多了兩個新東西,來解釋一下他們分別的作用:
還記得在新增 model 時有設定幾個欄位嗎?以 Employer 為例就是 first_name、last_name、age,而當我們用了這個 fields變數,就可以控制在 表單新增 Employer 的時候,要設定哪些欄位。
目前這個寫法 fields = '__all__' 就是全部欄位都要出現的意思。
另外一種寫法是像這樣: fields = ['first_name','last_name'],一次只顯示兩個欄位。
Ps. 不懂的話沒關係,等等會有實際案例
這段的意思是,當你成功新增物件時(也就是當你填好欄位,按下新增按鈕時),會重導到指定的頁面,現在我們這樣設定,當我們新增完,會回到 name = employer-list 的頁面,也就是 http://127.0.0.1:8000/online/employers/
再來就是畫面的地方了,Create 的 templates 比較特別,先照著以下步驟做,等等再解釋:
新增表單的 templates -> EmployerCreate 對應的 templates 路徑是 store/online/templates/online/employer_form.html
有沒有發現,跟前面的 employer_list 比起來,create 的 templates 不是 employer_create 而是 employer_form.html,這個檔案是 create 和 update 共用的,之後提到 update 時會解釋更清楚
這個寫法跟 ROR 蠻像的,因為 ROR 也可以把 create 和 edit 頁面,用 _form 檔案一起呈現
<!-- store/online/templates/online/employer_form.html -->
{% extends 'sidebar.html' %}
{% block content %}
<h2>{% if request.resolver_match.url_name == 'employer-create' %}新增{% else %}編輯{% endif %} Employer</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">儲存</button>
</form>
<a href="{% url 'employer-list' %}">返回列表</a>
{% endblock %}
來介紹一下這一段在幹嘛:
url 是 employer-create,那就顯示 新增 文字,如果不是的話就是顯示 編輯 文字post
{{ form.as_p }} 會將表單的每個欄位以段落 <p> 標籤 的形式呈現我們來看一下現在畫面長麼樣子,瀏覽器輸入剛剛 urls.py 設定好的路徑 http://127.0.0.1:8000/online/employer/create/:

可以在圖上發現幾個重點:
http://127.0.0.1:8000/online/employer/create/,確實是渲染我剛剛創建的 employer_form.html templates 畫面class EmployerCreate 那邊是這樣寫: fields = '__all__'
{{ form.as_p }} 的確有把 Employer 所有欄位,都用 <p> 包起來{% if request.resolver_match.url_name == 'employer-create' %}新增{% else %}編輯{% endif %} Employer 這一段比較難懂,我們下面說明這一段看起來有點複雜,不過沒關係,我們把它印出來看到底是什麼,就不用擔心了,一樣在剛剛 employer_form.html 的頁面底下增加這幾行!
<!-- store/online/templates/online/employer_form.html -->
{% extends 'sidebar.html' %}
{% block content %}
<!-- ...省略 -->
<p>request------ {{ request }}</p>
<p>request.resolver_match------{{ request.resolver_match }}</p>
<p>request.resolver_match.url_name ------ {{ request.resolver_match.url_name }}</p>
{% endblock %}
然後看一下我們網頁目前的截圖:

應該就知道這一段是在幹嘛了,簡單講就是說,到每一個網頁,都會有不同的 request,現在到 http://127.0.0.1:8000/online/employer/create/ 路徑的 request 是上面印的那樣,我們利用這個 request 印出我們想要印出的文字,如果今天的 request 不是我們想要的,就印出其他的文字
而現在此頁面的 request-url_name 是 employer-create,因此我想要印出 新增 這兩個字
Ps. 測試完記得刪掉這些 request文字 喔~
ROR 的表單沒有這麼複雜,因為厲害的 form_with 功能幫你做到很多事情!
前面有提到如果今天這樣設定 fields = ['first_name','last_name'] ,就可以修改 form 表單的欄位,現在就來試試看吧,到 views.py 改成下面那樣:
# online/views.py
class EmployerCreate(CreateView):
model = Employer
fields = ['first_name','last_name']
success_url = reverse_lazy('employer-list')
現在的畫面會長這樣,欄位真的剩下指定的兩個!

Ps. 測試完記得改完 fields = '__all__'
最後輸入資料點下儲存後,正常來說應該會成功回到 http://127.0.0.1:8000/online/employers/ 這個頁面,原因還記得嗎?是因為當初設定 success_url = reverse_lazy('employer-list') 這一段的原因!
今天學到哪些東西呢?
最後附上 Github: https://github.com/eagle0526/Django-store